package com.tbit.uqbike.webmanager.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tbit.common.constant.MethodEnum;
import com.tbit.common.constant.ModuleEnum;
import com.tbit.common.constant.OperationPlatform;
import com.tbit.common.entity.UserOpLog;
import com.tbit.common.enums.OperaPswEnum;
import com.tbit.uqbike.annos.OperateLog;
import com.tbit.uqbike.constant.UserConstant;
import com.tbit.uqbike.enums.SystemCodeEnum;
import com.tbit.uqbike.manager.exception.BaseException;
import com.tbit.uqbike.object.business.UserInfo;
import com.tbit.uqbike.object.pojo.RideCard;
import com.tbit.uqbike.object.pojo.RideCardUserExtendLog;
import com.tbit.uqbike.object.pojo.RideCardUserExtendLogDetail;
import com.tbit.uqbike.object.pojo.UserMember;
import com.tbit.uqbike.object.pojo.dto.PackageDelayDTO;
import com.tbit.uqbike.object.pojo.dto.RideCardUserDelayDTO;
import com.tbit.uqbike.object.pojo.vo.GiveRideCardTemplateVO;
import com.tbit.uqbike.object.value.LoginInfo;
import com.tbit.uqbike.object.view.JsonResult;
import com.tbit.common.entity.view.PageResult;
import com.tbit.common.entity.view.Result;
import com.tbit.uqbike.service.business.OperaPswService;
import com.tbit.uqbike.service.business.RideCardService;
import com.tbit.uqbike.service.rpcservice.PurviewService;
import com.tbit.uqbike.webmanager.business.user_op_log.service.UserOpLogService;
import com.tbit.uqbike.webmanager.util.Assert;
import com.tbit.uqbike.webmanager.util.ServletUtils;
import com.tbit.uqbike.webmanager.util.excel.ExcelUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;

/**
 * 骑行会员
 *
 * @author Leon
 * 2019年9月24日 下午4:10:05
 */
@Validated
@RestController
@RequestMapping(value = "/rideCard", produces = BaseController.MEDIA_JSON_UTF8)
public class RideCardController extends BaseController {
    @Autowired
    private RideCardService rideCardService;
    @Autowired
    private PurviewService purviewService;
    @Autowired
    private UserOpLogService userOpLogService;
    @Autowired
    private OperaPswService operaPswService;

    /**
     * 查询所有骑行会员卡
     *
     * @param accountId
     * @param feeId
     * @param rowCount
     * @param pageNO
     * @param request
     * @return
     */
    @RequestMapping("/queryPage")
    public JsonResult queryPage(Integer accountId, Integer feeId,
                                @RequestParam(defaultValue = "10") Integer rowCount,
                                @RequestParam(defaultValue = "1") Integer pageNO,
                                HttpServletRequest request) {

        LoginInfo info = getLogin(request);
        if (!info.type.equals(UserConstant.USER_AGENT)) {
            Assert.notNull(accountId, "ver.accountId.notNull");
            //权限验证
            if (!purviewService.purviewCheck(info.id, accountId)) {
                throw new BaseException(SystemCodeEnum.NO_PRIVILEGE);
            }
        } else {
            accountId = info.id;
        }
        /** 查询所有会员卡 */
        List<RideCard> list = rideCardService.queryPage(accountId, feeId, pageNO, rowCount);
        /* 获取总数 */
        Integer total = rideCardService.queryCount(accountId, feeId);

        return JsonResult.ok(list, total);
    }

    /**
     * 添加
     */
    @RequestMapping("/add")
    @OperateLog(module = ModuleEnum.RIDECARD, methods = MethodEnum.RIDECARD_ADD)
    public JsonResult add(@RequestBody RideCard rideCard, HttpServletRequest request) {

        if (rideCard.getName().length() > 100) {
            throw new BaseException("骑行卡名称过长");
        }
        if (Objects.nonNull(rideCard.getDescription()) && rideCard.getDescription().length() > 255) {
            throw new BaseException("骑行卡描述过长");
        }
        if (Objects.nonNull(rideCard.getRemark()) && rideCard.getRemark().length() > 255) {
            throw new BaseException("骑行卡备注过长");
        }
        if (Objects.nonNull(rideCard.getDiscountDes()) && rideCard.getDiscountDes().length() > 200) {
            throw new BaseException("骑行卡折扣描述过长");
        }

        if (rideCard.getTimeCount() == 0){
            throw new BaseException("减免时长或减免费用不能为0");
        }

        LoginInfo info = getLogin(request);
        if (!info.type.equals(UserConstant.USER_AGENT)) {
            Assert.notNull(rideCard.getAccountId(), "ver.accountId.notNull");
            //权限验证
            if (!purviewService.purviewCheck(info.id, rideCard.getAccountId())) {
                throw new BaseException(SystemCodeEnum.NO_PRIVILEGE);
            }
        } else {
            rideCard.setAccountId(info.id);
        }
        Assert.notNull(rideCard.getType(), "ver.type.notNull");
        Assert.notNull(rideCard.getUserType(), "请选择使用范围");
        Assert.notNull(rideCard.getName(), "ver.name.notNull");
        Assert.notNull(rideCard.getMoney(), "ver.money.notNull");
        if (rideCard.getMoney() <= 0) {
            throw new BaseException(SystemCodeEnum.AMMOUNT_MUST_GREATER_THAN_0);
        }
        if (rideCard.getEnable() == null) {
            rideCard.setEnable(true);
        }
        if (rideCard.getDescription() == null) {
            rideCard.setDescription("");
        }
        if (rideCard.getRemark() == null) {
            rideCard.setRemark("");
        }
        if (rideCard.getTimeCount() == null) {
            rideCard.setTimeCount(0);
        }
        if (rideCard.getMaxRide() == null) {
            rideCard.setMaxRide(0);
        }
        rideCardService.insert(rideCard);

        // 插入用户操作日志
        UserInfo loginInfo = BaseController.fetchUserInfo();
        userOpLogService.insertSingle(UserOpLog.builder()
                .accountId(rideCard.getAccountId())
                .opUser(loginInfo.getName())
                .opUserPhone(loginInfo.getPhone())
                .operation("骑行卡套餐变动")
                .opType("创建")
                .opPlatform(OperationPlatform.MANAGER.code)
                .opTime(LocalDateTime.now())
                .detail("套餐名称: " + rideCard.getName())
                .result(true)
                .build());

        return JsonResult.ok();
    }

    /**
     * 修改信息
     */
    @RequestMapping("/edit")
    @OperateLog(module = ModuleEnum.RIDECARD, methods = MethodEnum.RIDECARD_EDIT)
    public JsonResult edit(@RequestBody RideCard rideCard, HttpServletRequest request) {
        if (rideCard.getName().length() > 100) {
            throw new BaseException("骑行卡名称过长");
        }
        if (Objects.nonNull(rideCard.getDescription()) && rideCard.getDescription().length() > 255) {
            throw new BaseException("骑行卡描述过长");
        }
        if (Objects.nonNull(rideCard.getRemark()) && rideCard.getRemark().length() > 255) {
            throw new BaseException("骑行卡备注过长");
        }
        if (Objects.nonNull(rideCard.getDiscountDes()) && rideCard.getDiscountDes().length() > 200) {
            throw new BaseException("骑行卡折扣描述过长");
        }
        LoginInfo info = getLogin(request);
        if (!info.type.equals(UserConstant.USER_AGENT)) {
            Assert.notNull(rideCard.getAccountId(), "ver.accountId.notNull");
            //权限验证
            if (!purviewService.purviewCheck(info.id, rideCard.getAccountId())) {
                throw new BaseException(SystemCodeEnum.NO_PRIVILEGE);
            }
        } else {
            rideCard.setAccountId(info.id);
        }
        Assert.notNull(rideCard.getRideCardId(), "ver.ridecard.notNull");
        if (rideCard.getMoney() != null && rideCard.getMoney() <= 0) {
            throw new BaseException(SystemCodeEnum.AMMOUNT_MUST_GREATER_THAN_0);
        }
        RideCard rideCardDB = rideCardService.getById(rideCard.getRideCardId());
        if (rideCardDB == null) {
            throw new BaseException(SystemCodeEnum.RIDECARD_NOT_EXIST);
        }
        if (rideCard.getName() != null) {
            rideCardDB.setName(rideCard.getName());
        }
        if (rideCard.getEnable() != null) {
            rideCardDB.setEnable(rideCard.getEnable());
        }
        if (rideCard.getDescription() != null) {
            rideCardDB.setDescription(rideCard.getDescription());
        } else {
            rideCardDB.setDescription("");
        }
        if (rideCard.getRemark() != null) {
            rideCardDB.setRemark(rideCard.getRemark());
        } else {
            rideCardDB.setRemark("");
        }
        if (Objects.nonNull(rideCard.getSort())){
            rideCardDB.setSort(rideCard.getSort());
        }
        rideCardDB.setShelfStartTime(rideCard.getShelfStartTime());
        rideCardDB.setShelfEndTime(rideCard.getShelfEndTime());
        rideCardService.edit(rideCardDB);

        return JsonResult.ok();
    }

    /**
     * 更新排序
     * @param rideCard rideCard
     * @return Result
     */
    @PostMapping("/updateSort")
    public Result<Object> updateSort(@RequestBody RideCard rideCard) {
        if (Objects.isNull(rideCard.getRideCardId()) || Objects.isNull(rideCard.getSort()) || Objects.isNull(rideCard.getNewSort())){
            return Result.error("参数不能为空");
        }
        if (rideCard.getNewSort() > 200){
            return Result.error("排序值不能大于200");
        }
        return rideCardService.updateSort(rideCard);
    }

    /**
     * 置为失效
     * @param request
     * @return
     */
    @RequestMapping("/editEnable")
    @OperateLog(module = ModuleEnum.RIDECARD, methods = MethodEnum.RIDECARD_CANCAL)
    public JsonResult editEnable(@RequestBody RideCard rideCard, HttpServletRequest request) {
        LoginInfo info = getLogin(request);
        if (!info.type.equals(UserConstant.USER_AGENT)) {
            Assert.notNull(rideCard.getAccountId(), "ver.accountId.notNull");
            //权限验证
            if (!purviewService.purviewCheck(info.id, rideCard.getAccountId())) {
                throw new BaseException(SystemCodeEnum.NO_PRIVILEGE);
            }
        } else {
            rideCard.setRideCardId(info.id);
        }
        rideCardService.editEnable(rideCard.getRideCardId(), rideCard.getAccountId());
        return JsonResult.ok();
    }

    /**
     * 用户购买的免押套餐记录分页
     *
     * @param userId
     * @param rowCount
     * @param pageNO
     * @return
     */
    @RequestMapping("/userRideCardPage")
    public JsonResult userRideCardPage(Integer userId,
                                       @RequestParam(defaultValue = "10") Integer rowCount,
                                       @RequestParam(defaultValue = "1") Integer pageNO) {
        Assert.notNull(userId, "ver.userId.notNull");
        /*获取总数*/
        Integer total = rideCardService.userRideCardCount(userId);
        if (total <= 0) {
            return JsonResult.ok(Collections.emptyList(), total);
        }
        List<UserMember> userMembers = rideCardService.userRideCardPage(userId, rowCount, pageNO);
        return JsonResult.ok(userMembers, total);
    }

    /**
     * 延长骑行卡到期时间
     *
     * @param delayDTO 。
     * @return 。
     */
    @PostMapping("/modifyExpireTime")
    public Result<String> modifyExpireTime(@RequestBody @Validated PackageDelayDTO delayDTO) {
        delayDTO.valid("骑行卡套餐");
        operaPswService.checkOperaPsw(BaseController.getLogin(ServletUtils.getRequest()),
                OperaPswEnum.OPERA_PSW_COUPONS_CONFIG.getModule(), delayDTO.getPwd());
        return rideCardService.modifyRideCardExpireTime(delayDTO);
    }

    /**
     * 卡券套餐到期时间更改
     *
     * @param delayDTO           .
     * @param httpServletRequest .
     * @return .
     */
    @PostMapping("/user/delay")
    public Result<String> rideCardUserDelay(@RequestBody @Validated RideCardUserDelayDTO delayDTO, HttpServletRequest httpServletRequest) {
        LoginInfo login = getLogin(httpServletRequest);
        delayDTO.setLoginInfo(login);
        operaPswService.checkOperaPsw(login, OperaPswEnum.OPERA_PSW_COUPONS_CONFIG.getModule(), delayDTO.getPwd());
        return rideCardService.rideCardUserDelay(delayDTO);
    }

    /**
     * 延长记录分页
     *
     * @param accountId 运营区域id
     * @param phone     手机号
     * @param page      页码
     * @param size      每页条数
     * @return .
     */
    @GetMapping("/extendLogListPage")
    public Result<PageResult<RideCardUserExtendLog>> extendLogListPage(@RequestParam Integer accountId, String phone, Date startTime, Date endTime,
                                                                       @RequestParam(required = false, defaultValue = "1") Integer page,
                                                                       @RequestParam(required = false, defaultValue = "10") Integer size) {
        return rideCardService.extendLogListPage(Page.of(page, size), accountId, phone, startTime, endTime);
    }


    /**
     * 延长记录分页导出
     * @param accountId 运营区域id
     * @param phone     手机号
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @return filename
     */
    @GetMapping("/exportExtendLog")
    public Result<Object> exportExtendLog(Integer accountId, String phone, Date startTime, Date endTime) {
        List<RideCardUserExtendLog> list = rideCardService.extendLogListPage(Page.of(1, 65535), accountId, phone, startTime, endTime).getData().getList();

        String fileName = "卡券到期时间更新记录";
        if (Objects.nonNull(startTime) && Objects.nonNull(endTime)){
            if (DateUtil.betweenMonth(startTime, endTime, true) > 6){
                return Result.error("仅允许导出6个月的数据");
            }
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            fileName = String.format("%s~%s 卡券到期时间更新记录", sdf.format(startTime), sdf.format(endTime));
        }

        ExcelUtil<RideCardUserExtendLog> excelUtil = new ExcelUtil<>(RideCardUserExtendLog.class);
        JsonResult result = excelUtil.exportExcel(list, fileName);
        return Result.success(result.getData());
    }


    /**
     * 延长记录详情分页
     *
     * @param logId 运营区域id
     * @param phone 手机号
     * @param page  页码
     * @param size  每页条数
     * @return .
     */
    @GetMapping("/extendLogDetailListPage")
    public Result<PageResult<RideCardUserExtendLogDetail>> extendLogDetailListPage(@RequestParam Integer logId, String phone,
                                                                                   @RequestParam(required = false, defaultValue = "1") Integer page,
                                                                                   @RequestParam(required = false, defaultValue = "10") Integer size) {
        return rideCardService.extendLogDetailListPage(Page.of(page, size), logId, phone);
    }

    /**
     * 修改用户免押卡次数
     *
     * @param userId
     * @param rideCardId
     * @param type
     * @return com.tbit.uqbike.object.view.JsonResult
     * @Description: 修改用户免押卡次数
     * @createDate 2020/10/29 14:39
     */
    @RequestMapping("/userRideCardEdit")
    @OperateLog(module = ModuleEnum.RIDECARD, methods = MethodEnum.USERRIDECARD_EDIT)
    public JsonResult userRideCardEdit(Integer userId, Integer rideCardId, Integer type, String orderNO, Integer useCount,
                                       Integer maxRide, String operaPsw) {
        Assert.notNull(userId, "ver.userId.notNull");
        Assert.notNull(type, "ver.type.notNull");
        Assert.notNull(orderNO, "ver.time.notNull");
        Assert.notNull(orderNO, "ver.brandId.notNull");
        /**操作密码校验*/
        operaPswService.checkOperaPsw(getLogin(ServletUtils.getRequest()), OperaPswEnum.OPERA_PSW_COUPONS_CONFIG.getModule(), operaPsw);

        UserMember userMember = rideCardService.getByOrderNO(orderNO);
        useCount = Optional.ofNullable(userMember.getUseCount()).orElse(0);
        if (userMember.getIsValid() == 0) {
            throw new BaseException(SystemCodeEnum.RIDECARDUSER_IS_INVALID);
        }
        if (useCount == 0 && type == 0) {
            throw new BaseException(SystemCodeEnum.RIDECARD_EDIT_ERROR);
        }
        HashMap<String, Object> map = new HashMap<>();
        RideCard rideCard = rideCardService.getById(rideCardId);
        map.put("userType", rideCard.getUserType());
        rideCardService.EdituserRideCard(map, userId, rideCardId, type, orderNO, useCount, maxRide);
        if (Objects.equals(rideCard.getUserType(), 1) && type < 2) {
            if (rideCard.getMaxRide() - userMember.getCurrentNum() <= 0) {
                throw new BaseException("可使用次数超过每日上限,不可添加使用次数");
            }
            int updateCount = type == 1 ? userMember.getCurrentNum() + 1 : Math.max(userMember.getCurrentNum() - 1, 0);
            rideCardService.updateCurrentNumByOrderNo(userMember.getOrderNO(), updateCount);
        }
        return JsonResult.ok();
    }


    /**
     * 查询骑行卡模板
     * @param accountId 品牌id
     * @param pageNO 页数
     * @param pageCount 条数
     * @return result
     */
    @GetMapping("/queryTemplate")
    public Result<PageResult<RideCard>> queryTemplate(Integer accountId, Integer pageNO, Integer pageCount) {
        if (Objects.isNull(accountId)) {
            return Result.error("请选择品牌");
        }
        return rideCardService.queryTemplate(accountId, pageNO, pageCount);
    }



    /**
     * 添加骑行卡模板
     * @param rideCard 骑行卡
     * @return result
     */
    @PostMapping("/addTemplate")
    @OperateLog(module = ModuleEnum.RIDECARD, methods = MethodEnum.RIDECARD_TEMPLATE_ADD)
    public Result<Object> addRideCardTemplate(@RequestBody RideCard rideCard){
        Assert.notNull(rideCard.getType(), "ver.type.notNull");
        Assert.notNull(rideCard.getUserType(), "请选择使用范围");
        Assert.notNull(rideCard.getName(), "ver.name.notNull");
        Assert.notNull(rideCard.getMoney(), "ver.money.notNull");
        if (rideCard.getName().length() > 100) {
            throw new BaseException("骑行卡名称过长");
        }
        if (Objects.nonNull(rideCard.getDescription()) && rideCard.getDescription().length() > 255) {
            throw new BaseException("骑行卡描述过长");
        }
        if (Objects.nonNull(rideCard.getRemark()) && rideCard.getRemark().length() > 255) {
            throw new BaseException("骑行卡备注过长");
        }
        if (Objects.nonNull(rideCard.getDiscountDes()) && rideCard.getDiscountDes().length() > 200) {
            throw new BaseException("骑行卡折扣描述过长");
        }
        if (rideCard.getMoney() <= 0) {
            throw new BaseException(SystemCodeEnum.AMMOUNT_MUST_GREATER_THAN_0);
        }
        if (rideCard.getEnable() == null) {
            rideCard.setEnable(true);
        }
        if (rideCard.getDescription() == null) {
            rideCard.setDescription("");
        }
        if (rideCard.getRemark() == null) {
            rideCard.setRemark("");
        }
        if (rideCard.getTimeCount() == null) {
            rideCard.setTimeCount(0);
        }
        if (rideCard.getMaxRide() == null) {
            rideCard.setMaxRide(0);
        }
        return rideCardService.addRideCardTemplate(rideCard);
    }

    /**
     * 编辑骑行卡模板
     * @param rideCard rideCard
     * @return reslut
     */
    @PostMapping("/updateTemplate")
    @OperateLog(module = ModuleEnum.RIDECARD, methods = MethodEnum.RIDECARD_TEMPLATE_UPD)
    public Result<Object> updateTemplate(@RequestBody RideCard rideCard){
        if (rideCard.getName().length() > 100) {
            throw new BaseException("骑行卡名称过长");
        }
        if (Objects.nonNull(rideCard.getDescription()) && rideCard.getDescription().length() > 255) {
            throw new BaseException("骑行卡描述过长");
        }
        if (Objects.nonNull(rideCard.getRemark()) && rideCard.getRemark().length() > 255) {
            throw new BaseException("骑行卡备注过长");
        }
        if (Objects.nonNull(rideCard.getDiscountDes()) && rideCard.getDiscountDes().length() > 200) {
            throw new BaseException("骑行卡折扣描述过长");
        }
        return rideCardService.updateTemplate(rideCard);
    }


    /**
     * 删除模板
     * @param rideCardId 模板id
     * @return result
     */
    @DeleteMapping("/deleteTemplate")
    @OperateLog(module = ModuleEnum.RIDECARD, methods = MethodEnum.RIDECARD_TEMPLATE_DEL)
    public Result<Object> deleteTemplate(Integer rideCardId){
        if (Objects.isNull(rideCardId)){
            return Result.error("请选择需要删除的模板");
        }
        return rideCardService.deleteTemplate(rideCardId);
    }


    /**
     * 批量赠送骑行卡
     * @param file          文件
     * @param accountId     区域id
     * @param rideCardId    骑行卡id
     * @param remark        备注
     * @param psw           操作密钥
     * @return              Result
     */
    @PostMapping("/batchGiveRideCard")
    public Result<Object> batchGiveRideCard(MultipartFile file, Integer accountId, Integer rideCardId, String remark,
                                            String psw, HttpServletRequest request) {
        LoginInfo login = getLogin(request);
        /**操作密码校验*/
        if (Objects.isNull(file) || Objects.isNull(accountId) || Objects.isNull(rideCardId) || StrUtil.isBlank(remark)){
            return Result.error("参数异常，不能为空");
        }
        operaPswService.checkOperaPsw(login, OperaPswEnum.OPERA_PSW_COUPONS_CONFIG.getModule(), psw);
        return rideCardService.batchGiveRideCard(file, accountId, rideCardId, remark, login);
    }


    /**
     * 下载批量赠送骑行卡模板
     * @return Result
     */
    @GetMapping("/downloadTemplate")
    public Result<Object> downloadTemplate() {
        List<GiveRideCardTemplateVO> list = new ArrayList<>();
        list.add(new GiveRideCardTemplateVO("15112347896"));

        ExcelUtil<GiveRideCardTemplateVO> excelUtil = new ExcelUtil<>(GiveRideCardTemplateVO.class);
        JsonResult result = excelUtil.exportExcel(list, "批量赠送骑行卡模板");
        return Result.success(result.getData());
    }

}
